package com.taiji.dianthus.util;

//引入相关包

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;

//引入第三方包

/**
 * @ClassName EncryptUtil
 * @Description
 * @Author H.M
 * @Date 2020/6/16
 */
public class EncryptUtil {
    //--------------AES---------------
    /**
     * 密匙，必须16位
     */
    private static final String KEY = "o9sgfb4m7446ww42";
    /**
     * 偏移量
     */
    private static final String OFFSET = "ruhatmfle50ihmbm";
    /**
     * 编码
     */
    private static final String ENCODING = "UTF-8";
    /**
     * 算法
     */
    private static final String ALGORITHM = "AES";
    /**
     * 默认的加密算法，CBC模式
     */
    private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";

    //---------------MD5-------------------
    /**
     * 密匙
     */
    private static final String MD5KEY = "9131450sopsr78pn";

    /**
     * AES加密
     *
     * @param data
     * @return String
     */
    public static String AESEncrypt(String data) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        SecretKeySpec skeySpec = new SecretKeySpec(KEY.getBytes("ASCII"), ALGORITHM);
        //CBC模式偏移量IV
        IvParameterSpec iv = new IvParameterSpec(OFFSET.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
        byte[] encrypted = cipher.doFinal(data.getBytes(ENCODING));
        //加密后再使用BASE64做转码
        return new Base64().encodeToString(encrypted);
    }

    /**
     * AES解密
     *
     * @param data
     * @return String
     */
    public static String AESDecrypt(String data) throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        SecretKeySpec skeySpec = new SecretKeySpec(KEY.getBytes("ASCII"), ALGORITHM);
        //CBC模式偏移量IV
        IvParameterSpec iv = new IvParameterSpec(OFFSET.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        //先用base64解码 输入参数应该进行base64校验，
        // 如果参数base64解码 数组不为16的倍数 即输入参数格式不对
        byte[] buffer = new Base64().decode(data);
        if (checkByteArray(buffer)) {
            byte[] encrypted = cipher.doFinal(buffer);
            return new String(encrypted, ENCODING);
        } else {
            return null;
        }

    }

    //---------------------MD5--------------------

    /**
     * MD5方法
     *
     * @param text 明文
     * @return 密文
     */
    public static String MD5encrypt(String text) throws Exception {
        //结果字符串
        String result = "";
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(text.getBytes());
            byte b[] = md.digest();
            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            result = buf.toString();
           /* System.out.println("MD5(" + text + ",32小写) = " + result);
            System.out.println("MD5(" + text + ",32大写) = " + result.toUpperCase());
            System.out.println("++++++++++++++++++++++++各位大哥借过+++++++++++++++++++++++");
            System.out.println("MD5(" + text + ",16小写) = " + buf.toString().substring(8, 24));
            System.out.println("MD5(" + text + ",16大写) = " + buf.toString().substring(8, 24).toUpperCase());*/
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * MD5验证方法
     *
     * @param text 明文
     * @param md5  密文
     * @return true/false
     */
    public static boolean verify(String text, String md5) throws Exception {
        //根据传入的密钥进行验证
        String md5Text = MD5encrypt(text);
        if (md5Text.equalsIgnoreCase(md5)) {
            return true;
        }
        return false;
    }

    /**
     * 生成16位不重复的随机数，含数字+大小写
     *
     * @return
     */
    public static String getGUID() {
        StringBuilder uid = new StringBuilder();
        //产生16位的强随机数
        Random rd = new SecureRandom();
        for (int i = 0; i < 16; i++) {
            //产生0-2的3位随机数
            int type = rd.nextInt(3);
            switch (type) {
                case 0:
                    //0-9的随机数
                    uid.append(rd.nextInt(10));
                    break;
                case 1:
                    //ASCII在65-90之间为大写,获取大写随机
                    uid.append((char) (rd.nextInt(25) + 65));
                    break;
                case 2:
                    //ASCII在97-122之间为小写，获取小写随机
                    uid.append((char) (rd.nextInt(25) + 97));
                    break;
                default:
                    break;
            }
        }
        return uid.toString();
    }

    /**
     * byte数据校验
     *
     * @param bytes
     * @return
     */
    public static boolean checkByteArray(byte[] bytes) {
        if (null != bytes && bytes.length > 0) {
            if (bytes.length % 16 != 0) {
                return false;
            } else {
                return true;
            }
        } else {
            return false;
        }
    }

}
